package com.usermanagement.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usermanagement.constant.ResultCodeConstant;
import com.usermanagement.dto.AssignPermissionDTO;
import com.usermanagement.dto.LoginDTO;
import com.usermanagement.dto.ResetPasswordDTO;
import com.usermanagement.dto.UserDTO;
import com.usermanagement.entity.UserDO;
import com.usermanagement.exception.BusinessException;
import com.usermanagement.mapper.UserMapper;
import com.usermanagement.service.UserService;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    @Transactional
    public Boolean registerUser(UserDTO userDTO) {
        QueryWrapper<UserDO> wrapper = Wrappers.query();
        wrapper.eq("username", userDTO.getUsername()).or().eq("email", userDTO.getEmail());
        UserDO existingUser = userMapper.selectOne(wrapper);
        if (existingUser != null) {
            throw new BusinessException(ResultCodeConstant.CODE_000001, ResultCodeConstant.CODE_000001_MSG);
        }
        UserDO userDO = new UserDO();
        userDO.setUsername(userDTO.getUsername());
        userDO.setPasswordHash(userDTO.getPasswordHash());
        userDO.setEmail(userDTO.getEmail());
        userDO.setRole(userDTO.getRoleId() != null ? userMapper.selectByUserId(userDTO.getRoleId()).getRole() : null);
        userDO.setIdentity(userDTO.getIdentityId() != null ? userMapper.selectByUserId(userDTO.getIdentityId()).getIdentity() : null);
        userDO.setCreateBy(userDTO.getUserId());
        userDO.setCreateTime(new Date());
        userDO.setUpdateBy(userDTO.getUserId());
        userDO.setUpdateTime(new Date());
        return userMapper.insert(userDO) > 0;
    }

    @Override
    public UserDO loginUser(LoginDTO loginDTO) {
        UserDO userDO = userMapper.selectByUsernameOrEmail(loginDTO.getUsernameOrEmail(), loginDTO.getUsernameOrEmail());
        if (userDO == null) {
            throw new BusinessException(ResultCodeConstant.CODE_000002, ResultCodeConstant.CODE_000002_MSG);
        }
        if (!userDO.getPasswordHash().equals(loginDTO.getPasswordHash())) {
            throw new BusinessException(ResultCodeConstant.CODE_000003, ResultCodeConstant.CODE_000003_MSG);
        }
        return userDO;
    }

    @Override
    @Transactional
    public Boolean resetPassword(ResetPasswordDTO resetPasswordDTO) {
        UserDO userDO = userMapper.selectByUserId(resetPasswordDTO.getUserId());
        if (userDO == null) {
            throw new BusinessException(ResultCodeConstant.CODE_000004, ResultCodeConstant.CODE_000004_MSG);
        }
        userDO.setPasswordHash(resetPasswordDTO.getNewPasswordHash());
        userDO.setUpdateBy(resetPasswordDTO.getUserId());
        userDO.setUpdateTime(new Date());
        return userMapper.updateById(userDO) > 0;
    }

    @Override
    @Transactional
    public Boolean assignPermissions(AssignPermissionDTO assignPermissionDTO) {
        UserDO userDO = userMapper.selectByUserId(assignPermissionDTO.getUserId());
        if (userDO == null) {
            throw new BusinessException(ResultCodeConstant.CODE_000004, ResultCodeConstant.CODE_000004_MSG);
        }
        if (userMapper.countRoleById(assignPermissionDTO.getRoleId()) == 0 || userMapper.countIdentityById(assignPermissionDTO.getIdentityId()) == 0) {
            throw new BusinessException(ResultCodeConstant.CODE_000005, ResultCodeConstant.CODE_000005_MSG);
        }
        userDO.setRole(userMapper.selectByUserId(assignPermissionDTO.getRoleId()).getRole());
        userDO.setIdentity(userMapper.selectByUserId(assignPermissionDTO.getIdentityId()).getIdentity());
        userDO.setUpdateBy(assignPermissionDTO.getUserId());
        userDO.setUpdateTime(new Date());
        return userMapper.updateById(userDO) > 0;
    }
}